// Mm HTTP 响应通用类
export interface MmHttpResponse<T = unknown> {
  success: boolean;
  code: string;
  message?: string;
  data?: T;
}

/**
 * 服务器异常详情接口，用于封装在 `DebugInfo` 中的底层错误信息。
 *
 * 包含异常的类型、消息、根本原因和堆栈跟踪，是诊断服务器端错误的核心数据。
 *
 * ⚠️ **安全警告**：此信息**绝不能在生产环境暴露给前端用户**，仅用于开发、测试和运维日志分析。
 *
 * @interface ServerError
 *
 * @example
 * {
 *   "type": "DatabaseConnectionException",
 *   "message": "Failed to connect to PostgreSQL database",
 *   "cause": "Connection timed out after 5000ms",
 *   "stackTrace": "org.postgresql.util.PSQLException: Connection refused\n" +
 *                "  at org.postgresql.core.v3.ConnectionFactoryImpl.openConnection(...)\n" +
 *                "  at org.postgresql.jdbc.PgConnection.<init>(...)"
 * }
 *
 * @example
 * // Node.js 环境示例
 * {
 *   "type": "TypeError",
 *   "message": "Cannot read property 'id' of undefined",
 *   "cause": "User object was not loaded from database",
 *   "stackTrace": "TypeError: Cannot read property 'id' of undefined\n" +
 *                "    at UserController.processUser (...)\n" +
 *                "    at ..."
 * }
 *
 * @see DebugInfo.serverError
 * @see https://nodejs.org/api/errors.html JavaScript Error 对象参考
 * @see https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html Java Throwable 参考（如使用 JVM 后端）
 *
 * @since v1.0.0
 */
interface ServerError {
  /**
   * 异常的类型或类名，机器可读，用于分类错误。
   *
   * 通常对应后端编程语言中的异常类名。
   *
   * @example "ValidationError", "DatabaseException", "NullPointerException", "TypeError"
   */
  type: string;

  /**
   * 异常的简要描述信息，用于快速理解错误原因。
   *
   * 应清晰、具体，避免模糊信息如 "Something went wrong"。
   *
   * @example "Email format is invalid", "User with ID 123 not found"
   */
  message: string;

  /**
   * 异常的根本原因（可选），提供比 `message` 更深层的解释。
   *
   * 常用于链式异常（chained exceptions），说明“为什么”会发生此错误。
   *
   * @example "Connection pool exhausted", "Disk quota exceeded", "Upstream service returned 503"
   */
  cause?: string;

  /**
   * 完整的堆栈跟踪（Stack Trace），用于精确定位代码中的错误位置。
   *
   * 包含函数调用链和文件行号，是开发人员调试的最重要信息。
   *
   * ⚠️ **高度敏感**：包含代码结构、文件路径、依赖库等内部信息，生产环境必须过滤。
   *
   * @example
   * "Error: Cannot read property 'id' of null\n" +
   * "    at UserService.processData (/app/src/service/UserService.js:25:32)\n" +
   * "    at /app/src/controller/UserController.js:40:18"
   */
  stackTrace?: string;
}

/**
 * 调试信息接口，封装服务器端诊断所需的详细上下文。
 *
 * ⚠️ **安全警告**：此信息**仅在开发或测试环境返回**，生产环境必须过滤掉，以防止敏感信息泄露（如堆栈、内部服务名）。
 *
 * 用于开发人员或运维团队快速定位问题根源。
 *
 * @interface DebugInfo
 *
 * @example
 * {
 *   "timestamp": "2025-08-07T10:00:00.000Z",
 *   "requestId": "req-abc123xyz",
 *   "code": "DB_CONNECTION_TIMEOUT",
 *   "data": {
 *     "sql": "SELECT * FROM users WHERE id = ?",
 *     "params": [123],
 *     "timeout": 5000
 *   },
 *   "exception": {
 *     "name": "TimeoutError",
 *     "message": "Connection timed out after 5s",
 *     "stack": "Error: ...\n  at Pool.query (...)"
 *   }
 * }
 *
 * @see ServerError
 * @see ApiResponse.debugInfo
 *
 * @since v1.0.0
 */
interface DebugInfo {
  /**
   * 事件发生的时间戳，使用 ISO 8601 格式的 UTC 时间。
   *
   * 用于问题追踪和日志对齐。
   *
   * @example "2025-08-07T10:00:00.000Z"
   */
  timestamp: string;

  /**
   * 请求的唯一标识符（Request ID），用于全链路追踪（Tracing）。
   *
   * 通常由网关或入口服务生成，贯穿整个调用链，便于在日志系统中检索相关记录。
   *
   * @example "req-a1b2c3d4e5", "trace-9f8e7d6c"
   */
  requestId?: string;

  /**
   * 调试错误码，机器可读，用于分类和自动化处理。
   *
   * 比 `ApiResponse.code` 更具体，指向底层技术问题。
   *
   * @example "DB_TIMEOUT", "REDIS_DOWN", "VALIDATION_INTERNAL_ERROR"
   */
  code?: string;

  /**
   * 附加的调试数据，结构不固定，用于提供上下文信息。
   *
   * 可能包含：SQL 查询、API 参数、缓存键名、内部状态等。
   *
   * @example
   * {
   *   "query": "GET /api/users/123",
   *   "headers": { "Authorization": "Bearer ..." },
   *   "cacheKey": "user:profile:123"
   * }
   */
  data?: any;

  /**
   * 服务器抛出的异常对象详情。
   *
   * 包含异常名称、消息和完整的堆栈跟踪（Stack Trace）。
   *
   * 是诊断错误最直接的信息源。
   *
   * @see ServerError
   */
  serverError?: ServerError;
}

/**
 * 字段级校验结果接口，用于表示单个表单字段的校验失败详情。
 *
 * 通常作为 API 响应中 `fieldValidationErrors` 数组的元素类型，
 * 支持返回一个字段的多个校验错误（如：格式错误、必填、长度超限等）。
 *
 * @interface FieldError
 *
 * @example
 * // 后端返回示例
 * {
 *   "field": "email",
 *   "errors": [
 *     "邮箱格式不正确",
 *     "该邮箱已被注册"
 *   ],
 *   "value": "invalid-email"
 * }
 *
 * @example
 * // 前端使用示例（Arco Design / Formily 等）
 * form.setFields([
 *   {
 *     name: 'email',
 *     errors: result.errors,
 *     value: result.value
 *   }
 * ]);
 *
 * @see ApiResponse.fieldErrors
 * @see https://arco.design/react/components/form 表单组件集成示例
 *
 * @since v1.0.0
 */
export interface FieldError {
  /**
   * 出错的字段名称（字段路径）。
   *
   * 应与前端表单控件的 `name` 或 `field` 属性完全匹配，
   * 支持嵌套字段（如 `"user.profile.email"`）。
   * 支持数组嵌套字段（如 `"user[0].profile[1].email"`）。
   * @example "email", "password", "user.address.postalCode", "user[0].profile[1].email"
   */
  name: string;

  /**
   * 该字段的所有校验错误消息集合。
   *
   * 每条消息应为**用户可读的友好提示**，用于在 UI 上逐条显示。
   * 顺序通常按校验规则优先级排列。
   *
   * @example
   * [
   *   "邮箱格式不正确",
   *   "该邮箱已被注册"
   * ]
   */
  errors: string[];

  /**
   * 触发校验的原始字段值（可选）。
   *
   * 用于调试、日志记录或在错误提示中回显用户输入。
   *
   * ⚠️ 注意：出于安全考虑，敏感字段（如密码）通常不应返回此值。
   *
   * @example "invalid-email", "123456", "   "（空格）
   */
  value?: string;
}

/**
 * API 响应标准封装接口，用于统一后端返回结构。
 *
 * 所有 HTTP 接口应返回此格式的 JSON 响应，确保前端处理一致性。
 *
 * @template T - 响应中 `data` 字段的泛型类型，表示业务数据结构。
 *
 * @example
 * // 成功响应
 * {
 *   "success": true,
 *   "code": "OK",
 *   "message": "请求成功",
 *   "data": { "id": 1, "name": "张三" },
 *   "help": "您可以继续操作。",
 *   "links": { "profile": "/users/1" }
 * }
 *
 * @example
 * // 失败响应（含校验错误）
 * {
 *   "success": false,
 *   "code": "VALIDATION_ERROR",
 *   "message": "数据校验失败",
 *   "data": null,
 *   "fieldValidationErrors": [
 *     {
 *       "field": "email",
 *       "errors": [
 *         { "code": "REQUIRED", "message": "邮箱不能为空" }
 *       ]
 *     }
 *   ]
 * }
 *
 * @see {@link https://github.com/your-org/api-conventions API 响应规范文档}
 * @see FieldError
 * @see DebugInfo
 *
 * @since v1.0.0
 */
export interface ApiResponse<T> {
  /**
   * 请求是否成功。
   * - `true`：业务处理成功，`data` 中包含有效数据。
   * - `false`：业务处理失败（如校验失败、权限不足），`data` 通常为 `null`。
   */
  success: boolean;

  /**
   * 服务器返回的状态码或业务码。
   *
   * 用于机器识别错误类型，例如：
   * - `"OK"`：成功
   * - `"VALIDATION_ERROR"`：参数校验失败
   * - `"UNAUTHORIZED"`：未授权
   * - `"BUSINESS_RULE_VIOLATION"`：业务规则冲突
   *
   * @example "OK", "USER_NOT_FOUND", "INSUFFICIENT_BALANCE"
   */
  code: string;

  /**
   * 统一的消息提示，用于直接展示给用户。
   *
   * 应使用用户友好的语言，避免技术术语。
   *
   * @example "操作成功", "邮箱格式不正确", "系统繁忙，请稍后重试"
   */
  message: string;

  /**
   * 关联的业务数据。
   *
   * 类型由泛型 `T` 决定。请求失败时通常为 `null`。
   *
   * @example 用户信息、订单列表、分页元数据等
   */
  data: T | null;

  /**
   * 帮助提示信息，为用户提供下一步操作指引。
   *
   * 可选字段，用于增强用户体验。
   *
   * @example "请检查邮箱格式", "您可以在设置中修改密码", "联系客服获取帮助"
   */
  help?: string;

  /**
   * 关联的超链接集合，用于引导用户跳转。
   *
   * 键为语义化名称（如 `self`, `profile`, `next`），值为完整 URL。
   * 支持 HATEOAS 风格。
   *
   * @example
   * {
   *   "self": "https://api.example.com/users/123",
   *   "profile": "https://example.com/profile/123",
   *   "billing": "https://example.com/billing"
   * }
   */
  links?: Record<string, string>;

  /**
   * 表单字段级校验错误信息。
   *
   * 当 `success` 为 `false` 且错误源于输入数据时，此字段包含详细的字段错误。
   * 每个错误项可包含多个校验规则失败信息。
   *
   * @see FieldError
   *
   * @example
   * [
   *   {
   *     "field": "email",
   *     "errors": [
   *       { "code": "INVALID_FORMAT", "message": "邮箱格式不正确" }
   *     ]
   *   }
   * ]
   */
  fieldErrors?: FieldError[];

  /**
   * 调试信息，仅在开发或测试环境返回。
   *
   * ⚠️ **生产环境必须禁用**！避免泄露敏感信息（如堆栈、SQL、内部路径）。
   *
   * 用于开发人员定位问题。
   *
   * @example
   * {
   *   "requestId": "req-abc123",
   *   "timestamp": "2025-08-07T10:00:00Z",
   *   "stack": "Error: ...\n  at UserController.create...",
   *   "details": { "sqlQuery": "SELECT ..." }
   * }
   */
  debugInfo?: DebugInfo;
}
